program virtual_function;

    class Base1;
        virtual function void show();
                    $display("Base1::show");
        endfunction
    endclass

    class Derived1 extends Base1;
        /** 覆写(Override)父类方法
        * 在子类中覆写父类方法时，建议也加上virtual关键字（虽然不是必须的），
        * 这样可以提高代码的可读性，并且如果该子类又被进一步继承，保持方法的可覆写性。
        */
        virtual function void show();
            $display("Derived1::show");
        endfunction
    endclass

    // 无virtual关键字的情况
    class Base2;
        function void display();
            $display("Base2::display");
        endfunction
    endclass

    class Derived2 extends Base2;
        // 这不是真正的覆写，只是同名方法, 隐藏了父类的方法
        function void display();
            $display("Derived2::display");
        endfunction
    endclass

    initial begin
        Base1 b1;
        Derived1 d1;
        Base2 b2;
        Derived2 d2;

        // 测试有virtual的情况
        b1 = new();
        d1 = new();
        b1.show();       // 输出: Base1::show
        d1.show();       // 输出: Derived1::show
        b1 = d1;         // 基类引用指向派生类对象
        b1.show();       // 输出: Derived1::show (多态行为)

        // 测试无virtual的情况
        b2 = new();
        d2 = new();
        b2.display();    // 输出: Base2::display
        d2.display();    // 输出: Derived2::display
        b2 = d2;         // 基类引用指向派生类对象
        b2.display();    // 输出: Base2::display (静态绑定/早期绑定)
    end
endprogram
